#ifndef _SIGNED_REQUEST_CORE_HPP
#define _SIGNED_REQUEST_CORE_HPP 1

#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include "../constants.hpp"
#include "SignedMessage.hpp"
#include "RequestCore.hpp"

/** Request message sent from the client to the order node **/

namespace BFT
{
	namespace messages
	{

		class SignedRequestCore : public SignedMessage, public RequestCore
		{
			public:
			/**
			constructor that accepts specific message fields. This
			constructor builds the message bytes representation
			starting from where VerifiedMessageBase leaves off
			**/
			SignedRequestCore(uint32_t _clientId, uint32_t _requestId, boost::shared_ptr<char> _command, uint32_t _command_size);
			
			/**
			Constructor that accepts a byte represnetation of the message.
			Parses the byte representation to populate the class fields.
			**/
			SignedRequestCore(boost::shared_ptr<char> _buffer, uint32_t _buffer_size); 	

			SignedRequestCore(boost::shared_ptr<Entry> _entry);			
			
			uint32_t getSendingClient();
			
			boost::shared_ptr<Entry> getEntry(); //inlined

			uint32_t getRequestId();
			
			boost::shared_ptr<char> getCommand();
			
			uint32_t getCommandSize();

			bool equals(boost::shared_ptr<RequestCore> _other_rc);

			static uint16_t tag();
			
			boost::shared_ptr<char> getBytes(int& _bytes_length);
			
			uint32_t getTotalSize();
			
			uint16_t getTag();
			
			void printInfo();

			protected:

			/**
			total size of the request message
			**/
			uint32_t computeSize(boost::shared_ptr<Entry> _entry); //inlined
			
			boost::shared_ptr<Entry> entry;
			
			uint32_t requestId;
			boost::shared_ptr<char> command;
			uint32_t command_size;	
		};


		inline uint32_t SignedRequestCore::getSendingClient() {return entry.get()->getClient();}

		inline uint32_t SignedRequestCore::getRequestId() {return entry.get()->getRequestId();}

//		inline uint32_t SignedRequestCore::computeEntrySize(uint32_t _command_size) 
//			{return REQUEST_ID_SIZE + COMMAND_SIZE_SIZE + _command_size + CLIENT_ID_SIZE + COMMAND_DIGEST_FLAG_SIZE;}
		

		inline uint16_t SignedRequestCore::tag() {return SIGNED_REQUEST_CORE;}

		inline boost::shared_ptr<char> SignedRequestCore::getCommand() {return entry.get()->getCommand();}

		inline uint32_t SignedRequestCore::getCommandSize() {return entry.get()->getCommandSize();}
		
		inline boost::shared_ptr<Entry> SignedRequestCore::getEntry() {return entry;}
		
		inline uint32_t SignedRequestCore::computeSize(boost::shared_ptr<Entry> _entry) {return _entry.get()->getSize();} 

	} //namespace messages
} // namespace BFT

#endif
